package com.hsoft.zhxy.app.layout_03_01.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hsoft.zhxy.app.common.model.entity.JcqxGnzy;
import com.hsoft.zhxy.app.layout_03_01.mapper.LoginMapper;
import com.hsoft.zhxy.app.layout_03_01.model.query.LoginQuery;
import com.hsoft.zhxy.app.layout_03_01.model.vo.LoginVO;
import com.hsoft.zhxy.app.layout_03_01.service.LoginService;
import com.hsoft.zhxy.common.base.BaseService;
import com.hsoft.zhxy.common.exception.BizException;
import com.hsoft.zhxy.common.exception.ExcpCodeInfoEnum;
import com.hsoft.zhxy.common.redis.RedisClient;
import com.hsoft.zhxy.common.result.ResultBody;
import com.hsoft.zhxy.common.system.service.SystemService;
import com.hsoft.zhxy.common.util.EncryDESUtils;
import com.hsoft.zhxy.common.util.JwtTokenUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Random;

/**
 * All rights Reserved, Designed By 哈尔滨工业大学软件工程股份有限公司
 *
 * @Title: 登录操作 Service层接口实现类
 * @Package
 * @Description:
 * @author: system
 * @date: 2020-11-06
 */

@Service
public class LoginServiceImpl extends BaseService implements LoginService {

    @Autowired
    LoginMapper loginMapper;

    @Value("pwd.key")
    private String key;


    /**
     * 登录操作写入redis 前缀
     */
    private static final String LOGIN_PREFIX = "Login#Yzm#Prefix#";

    /**
     * 用户权限uri集合 缓存key前缀
     */
    private static final String YHQX_KEY_PREFIX = "Login#Gnzy#Prefix#";    // + yhid


    /**
     * 验证码超时时间 5分钟
     */
    private static final Long CODE_TIME_OUT = 300L;

    /**
     * 判断用户登录信息
     *
     * @param loginQuery
     * @param redisClient
     * @return
     */
    @Override
    public JSONObject checkUser(LoginQuery loginQuery, RedisClient redisClient) {
        Boolean hasCode = redisClient.hasKey(LOGIN_PREFIX + loginQuery.getCode());

        String code = "";

        if (hasCode) {
            code = redisClient.get(LOGIN_PREFIX + loginQuery.getCode());

            if (!code.equalsIgnoreCase(loginQuery.getCode().trim())) {
                //验证码校验失败
                throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0130);
            }
        } else {
            //验证码超时
            throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0311);
        }

//        String pwd = DigestUtils.sha512Hex(loginQuery.getPassWord());
        String pwd = "2176cc675ce4048552cf1cd0cb33d74988955937a5892084519dcaaa8e13cf4134c66e6ee07e7401430d62a89eae711ea371f622539129d539c2959c3c71ef0b";
        QueryWrapper<LoginVO> queryWrapper = new QueryWrapper<LoginVO>();
        queryWrapper.eq("yh.yhid", loginQuery.getUserName().trim()).eq("yh.yhzt", "1");
        //TODO 判断用户信息是否存在 不存在 放入redis

        LoginVO loginVO = loginMapper.getUserInfo(queryWrapper);

        if (loginVO == null) {
            //用户账户不存在
            throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0201);
        } else {
            //获取用户可登录方式
            String kdlfs = loginVO.getKdlfs();
            char[] kdlfsArr = kdlfs.toCharArray();

            if (kdlfsArr[1] == '1') {
                if (!pwd.equals(loginVO.getMm())) {
                    //密码错误
                    throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0122);
                }
            } else {
                //当前用户未授权通过自建用户密码方式登录
                throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0301);
            }
        }

        JSONObject returnJson = new JSONObject();

        String jwt = JwtTokenUtils.generateJsonWebToken(loginQuery.getUserName());

        if (!redisClient.hasKey(YHQX_KEY_PREFIX + loginVO.getYhid())) {
            returnJson.put("ynid", loginVO.getYhid());
            returnJson.put("yhxm", loginVO.getXm());
            returnJson.put("gnzy", this.getGnzyArray(loginVO.getYhid()).toString());
            redisClient.set(YHQX_KEY_PREFIX + loginVO.getYhid(), returnJson.toString());
        } else {
            String info = redisClient.get(YHQX_KEY_PREFIX + loginVO.getYhid());
            //TODO 需要验证
            returnJson = JSONObject.parseObject(info);
        }


        returnJson.put("jwt", jwt);

        return ResultBody.setData(returnJson);
    }

    /**
     * 获取功能资源数组
     * @param yhid
     * @return
     */
    private String getGnzyArray(String yhid) {
        List<JcqxGnzy> gnzyList = loginMapper.findListGnzyAll(yhid);
        JSONArray returnArray = new JSONArray();
        JSONArray gnzyArray = JSONArray.parseArray(JSONArray.toJSONString(gnzyList));

        for (int i = 0; i < gnzyArray.size(); i++) {
            JSONObject json = new JSONObject();
            JSONObject gnzyJson = gnzyArray.getJSONObject(i);
            if (StringUtils.isBlank(gnzyJson.getString("fcdid"))) {
                json.put("url", gnzyJson.getString("qqlj"));
                json.put("name", gnzyJson.getString("gnzymc"));
                json.put("icon",gnzyJson.getString("tb"));
                this.recursionGnzy(json,gnzyJson, gnzyArray);
                returnArray.add(json);
            }
        }

        return returnArray.toString();
    }

    /**
     * 递归拼接功能资源结构体
     * @param gnzyJson
     * @param gnzyArray
     */
    private void recursionGnzy(JSONObject gzyjson,JSONObject gnzyJson, JSONArray gnzyArray) {
        boolean hasChildren = false;
        JSONArray returnArray = new JSONArray();

        for (int i = 0; i < gnzyArray.size(); i++) {
            JSONObject zzyJson = gnzyArray.getJSONObject(i);
            JSONObject json = new JSONObject();
            if (gnzyJson.getString("gnzyid").equals(zzyJson.getString("fcdid"))) {
                hasChildren = true;

                if (gnzyJson.getInteger("sfwym") == 1) {
                    json.put("url", zzyJson.getString("qqlj"));
                    json.put("name", zzyJson.getString("gnzymc"));
                } else {
                    json.put("url", zzyJson.getString("qqlj"));
                    json.put("name", zzyJson.getString("gnzymc"));
                    json.put("icon",gnzyJson.getString("tb"));
                    this.recursionGnzy(json, zzyJson, gnzyArray);

                }
                returnArray.add(json);
            }
        }

        if (hasChildren) {
            gzyjson.put("children", returnArray);
        }
    }

    /**
     * 生成验证码
     *
     * @param redisClient
     * @return
     */
    @Override
    public JSONObject getCode(RedisClient redisClient) {
        // 创建一个随机数生成器类
        Random random = new Random();
        // randomCode用于保存随机产生的验证码，以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        //定义验证码长度
        final int codeCount = 4;
        //定义验证码生成的数组
        final char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字。
            String code = String.valueOf(codeSequence[random.nextInt(36)]);
            randomCode.append(code);
        }
        //将验证码写入redis
        redisClient.set(LOGIN_PREFIX + randomCode.toString(), randomCode.toString(), CODE_TIME_OUT);

        return ResultBody.setData(randomCode);
    }
}
